package mindmap.operation;

import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Pair;
import mindmap.components.node.SerializableNode;
import mindmap.components.node.node;
import mindmap.controller.layoutController;

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Vector;

public class FileOperation {

    Group pane1;
    Group pane2;

    public void setPane1(Group pane1) {
        this.pane1 = pane1;
    }

    public void setPane2(Group pane2) {
        this.pane2 = pane2;
    }


    //对于两侧布局的思维导图，中心结点的子节点需考虑分布在左侧还是右侧，分情况递归恢复
    private void restoreMap(SerializableNode root, node bmp) {
        ArrayList<SerializableNode> leaves = root.getLeaves();
        for(SerializableNode leaf : leaves) {//根据子节点的布局类型，分别恢复左右两侧布局
            if(leaf.getMapType().equals("left")) {
                node node = new node(bmp.root,bmp,bmp.getPane1(),bmp.getPane2(),"left");
                //恢复当前新建结点信息为leaf中存储的信息
                restoreData(leaf, node);
                bmp.addChrNode(node);
                restoreLeftPart(leaf, node);
            }
            else {
                node node = new node(bmp.root,bmp,bmp.getPane1(),bmp.getPane2(),"right");
                //恢复当前新建结点信息为leaf中存储的信息
                restoreData(leaf, node);
                bmp.addChrNode(node);
                restoreRightPart(leaf, node);
            }
        }
    }

    //恢复左侧布局
    private  void restoreLeftPart(SerializableNode parent, node lmp) {
        ArrayList<SerializableNode> leaves = parent.getLeaves();
        for(SerializableNode leaf : leaves) {
            node node = new node(lmp.root,lmp,lmp.getPane1(),lmp.getPane2(),"left");
            //恢复当前新建结点信息为leaf中存储的信息
            restoreData(leaf, node);
            lmp.addChrNode(node);
            restoreLeftPart(leaf, node);
        }
    }

    //恢复右侧布局
    private  void restoreRightPart(SerializableNode parent, node rmp) {
        ArrayList<SerializableNode> leaves = parent.getLeaves();
        for(SerializableNode leaf : leaves) {
            node node = new node(rmp.root,rmp,rmp.getPane1(),rmp.getPane2(),"right");
            //恢复当前新建结点信息为leaf中存储的信息
            restoreData(leaf, node);
            rmp.addChrNode(node);
            restoreRightPart(leaf, node);
        }
    }

    //将保存在NodeInformation中的信息恢复到思维导图结点Part中
    private  void restoreData(SerializableNode node, node mp) {
        mp.setLevel(node.getLevel());
        mp.setRectangleColor(new Color(node.getR1(), node.getG1(), node.getB1(), 1));
        mp.getLabel().setTextFill(new Color(node.getR2(), node.getG2(), node.getB2(), 1));
        mp.setBorderColor(new Color(node.getR3(), node.getG3(), node.getB3(), 1));
        mp.getLabel().setText(node.getText());
      //  mp.setBold(node.getBold());
        if(node.getBold()) {
            mp.getLabel().setFont(Font.font(node.getFontFamily(), FontWeight.EXTRA_BOLD, node.getFontSize()));
        }
        else  {
            mp.getLabel().setFont(Font.font(node.getFontFamily(), FontWeight.NORMAL, node.getFontSize()));
        }
        mp.getLabel().setUnderline(node.getUnderline());
      //  mp.getLabel().setFont(Font.font(node.getFontFamily(),node.getFontSize()));
        mp.getRectangle().setArcHeight(node.getRadius());
        mp.getRectangle().setArcWidth(node.getRadius());
        mp.arrangement = node.getMapType();
    }

    //遍历整个思维导图，保存每个结点信息以及层次结构
    public  void storeMap(SerializableNode parent, node mp) {
        if(mp.arrangement.equals("bilateral")){
            LinkedList<node> leftLeaves = mp.leftChildrenNode;
            for(node leaf : leftLeaves) {
                SerializableNode node = new SerializableNode();
                storeData(node, leaf);
                parent.getLeaves().add(node);
                storeMap(node, leaf);
            }
            LinkedList<node> rightLeaves = mp.rightChildrenNode;
            for(node leaf : rightLeaves) {
                SerializableNode node = new SerializableNode();
                storeData(node, leaf);
                parent.getLeaves().add(node);
                storeMap(node, leaf);
            }
        }
        else{
            LinkedList<node> leaves = mp.getChildrenNode();
            for(node leaf : leaves) {
                SerializableNode node = new SerializableNode();
                storeData(node, leaf);
                parent.getLeaves().add(node);
                storeMap(node, leaf);
            }
        }
    }

    //将思维导图结点Part中的数据存储到NodeInformation中
    private void storeData(SerializableNode node, node mp) {
        node.setLevel(mp.getLevel());
        node.setText(mp.label.getText());
        Color color1 = mp.getBorderColor(),
                color2 = (Color) mp.label.getTextFill(),
                color3 = mp.getRectangleColor();
        node.setNodeColor(color3.getRed(), color3.getGreen(), color3.getBlue());
        node.setFontColor(color2.getRed(), color2.getGreen(), color2.getBlue());
        node.setEdgeColor(color1.getRed(), color1.getGreen(), color1.getBlue());
        node.setMapType(mp.arrangement);
        node.setBold(mp.getBold());
        node.setUnderline(mp.getUnderline());
        node.setFontSize(mp.getLabel().getFont().getSize());
        node.setFontFamily(mp.getLabel().getFont().getFamily());
        node.setRadius(mp.getRectangle().getArcHeight());
    }

    public  node readFile(String fileName) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
        Object obj = ois.readObject();
        SerializableNode node = (SerializableNode) obj;
        ois.close();

        //根节点单独恢复，子节点通过递归恢复
        node mp = new node(null,null,pane1,pane2,"bilateral");
        mp.setLayoutX(200);
        mp.setLayoutY(200);
        restoreData(node, mp);
        layoutController.getInstance().treeView.setRoot(mp.getTreeItem());
        mp.setRoot(mp);
        restoreMap(node, mp);
        return mp;
    }

    public  void writeFile(node mp, String fileName) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
        SerializableNode nodeInfo = new SerializableNode();

        //根节点单独保存，子节点通过递归保存
        storeData(nodeInfo, mp);
        storeMap(nodeInfo, mp);

        oos.writeObject(nodeInfo);
        oos.close();
    }


}
